using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Text;

using System.Drawing.Imaging;

namespace ViewOnCore.Helper.Imaging
{
    public struct CatalogHeader
    {
        public short nNum1;
        public short nNum2;
        public int nThumbCount;
        public int nThumbWidth;
        public int nThumbHeight;
    }

    public struct CatalogItem
    {
        public int nItemSize;
        public int nItemID;
        public short nNum3;
        public short nNum4;
        public short nNum5;
        public short nNum6;
        public string strFileName;
        public short nNum7;
    }

    
    /// <summary>
	/// Summary description for ThumbDB.
	/// </summary>
	public class ThumbDB
	{
        private ArrayList m_arCatalogItems = new ArrayList();
        private string m_strThumbFile;

        public ThumbDB(string strThumbFile)
        {
            m_strThumbFile = strThumbFile;
            LoadCatalog();
        }

        public string[] GetThumbfiles()
        {
            String[] strFiles = new String[m_arCatalogItems.Count];
            
            int nIndex = 0;
            foreach(CatalogItem item in m_arCatalogItems)
            {
                strFiles[nIndex] = item.strFileName;
                nIndex++;
            }

            return strFiles;
        }

        public byte[] GetThumbData(String strFileName)
        {
            IStorageWrapper wrapper = new IStorageWrapper(m_strThumbFile, false);
            foreach(CatalogItem catItem in m_arCatalogItems)
            {
                if (catItem.strFileName == strFileName)
                {
                    String strStreamName = BuildReverseString(catItem.nItemID);
                    FileObject fileObject = wrapper.OpenUCOMStream(null, strStreamName);
                    if (fileObject == null || fileObject.Length == 0) continue;

                    Byte[] byRawData = new byte[fileObject.Length];
                    fileObject.Read(byRawData, 0, (int)fileObject.Length);
                    fileObject.Close();

                    // 3 ints of header data need to be removed
                    // Don't know what first int is.
                    // 2nd int is thumb index
                    // 3rd is size of thumbnail data.
                    Byte[] byData = new byte[byRawData.Length - 12];
                    for (int nIndex = 0; nIndex < byData.Length; nIndex++)
                        byData[nIndex] = byRawData[nIndex + 12];

                    return byData;
                }
            }

            return null;
        }

        public Size GetThumbnailSize(String strFileName)
        {
            Size xyThumb = new Size();
            foreach (CatalogItem catItem in m_arCatalogItems)
            {
                if (catItem.strFileName == strFileName)
                {
                    xyThumb.Width = xyThumb.Height = catItem.nItemSize;
                    break;
                }
            }

            return xyThumb;
        }

        public Image GetThumbnailImage(String strFileName)
        {
            Byte[] byThumbData = GetThumbData(strFileName);
            if (byThumbData == null)
                return null;

            String strTempFile = Path.GetTempFileName();
            MemoryStream ms = new MemoryStream(byThumbData);
            BinaryWriter binWriter = new BinaryWriter(File.Open(strTempFile, FileMode.OpenOrCreate));
            binWriter.Write(byThumbData);
            binWriter.Close();

            if (ms.Length > 0)
            {
                try
                {
                    Image img1 = Image.FromFile(strTempFile);
                    Image img2 = null;
                    if (img1 != null)
                        img2 = Image.FromStream(ms);

                    img1.Dispose();
                    img1 = null;

                    if (img2 != null)
                    {
                        File.Delete(strTempFile);
                        return img2;
                    }
                }
                catch (ArgumentException e)
                {
                    //MessageBox.Show(e.ToString());
                }
            }

            File.Delete(strTempFile);

            return null;
        }

        private void LoadCatalog()
        {
            IStorageWrapper wrapper = new IStorageWrapper(m_strThumbFile, false);
            FileObject fileObject = wrapper.OpenUCOMStream(null, "Catalog");
            String strTextData = String.Empty;
            if (fileObject != null)
            {
                Byte[] byFileData = new Byte [fileObject.Length];
                fileObject.Read(byFileData, 0, (int)fileObject.Length);
                MemoryStream ms = new MemoryStream(byFileData);
                BinaryReader br = new BinaryReader(ms);
                CatalogHeader ch = new CatalogHeader();
                ch.nNum1 = br.ReadInt16();
                ch.nNum2 = br.ReadInt16();
                ch.nThumbCount = br.ReadInt32();
                ch.nThumbWidth = br.ReadInt32();
                ch.nThumbHeight = br.ReadInt32();

                for (int nIndex = 0; nIndex < ch.nThumbCount; nIndex++)
                {
                    CatalogItem item = new CatalogItem();
                    item.nItemSize = br.ReadInt32();
                    item.nItemID = br.ReadInt32();
                    item.nNum3 = br.ReadInt16();
                    item.nNum4 = br.ReadInt16();
                    item.nNum5 = br.ReadInt16();
                    item.nNum6 = br.ReadInt16();
                    ushort usChar;
                    while((usChar = br.ReadUInt16()) != 0x0000)
                    {
                        Byte[] byChar = new Byte[2];
                        byChar[0] = (Byte)(usChar & 0x00FF);
                        byChar[1] = (Byte)((usChar & 0xFF00) >> 8);
                        item.strFileName += Encoding.Unicode.GetString(byChar);
                    }
                    item.nNum7 = br.ReadInt16();
                    m_arCatalogItems.Add(item);
                }
            }
        }

        private string BuildReverseString(int nItemID)
        {
            String strItem = nItemID.ToString();
            String strReverse = "";
            for (int nIndex = strItem.Length - 1; nIndex >= 0; nIndex--)
                strReverse += strItem[nIndex];

            return strReverse;
        }
	}
}
